package com.nintendo.service;

import com.nintendo.annotation.Table;
import com.nintendo.mapper.base.BaseDao;
import com.nintendo.utils.JdbcUtil;
import jdk.nashorn.internal.objects.NativeDebug;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class BaseDaoImpl<T> implements BaseDao<T> {
    @Override
    public boolean add(T t) {
        Connection connection = JdbcUtil.getConnection();
        Class<?> aClass = t.getClass();
//        String sql = "insert into user(name,age,type) values(?,?,?)";
        String sql = generateInsertSql(aClass);
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            Field[] fields = aClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                fields[i].setAccessible(true);
                Object value = fields[i].get(t);
                preparedStatement.setObject(i + 1, value);
            }
            int rowsAffected = preparedStatement.executeUpdate();
            return rowsAffected > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }
    public static String generateInsertSql(Class<?> aClass) {
        StringBuilder sqlBuilder = new StringBuilder();

        Field[] fields = aClass.getDeclaredFields();

        // 构建列名部分
        StringBuilder columns = new StringBuilder();
        // 构建占位符部分
        StringBuilder placeholders = new StringBuilder();

        for (int i = 0; i < fields.length; i++) {
            String fieldName = fields[i].getName();
            columns.append(fieldName);
            placeholders.append("?");
            if (i < fields.length - 1) {
                columns.append(", ");
                placeholders.append(", ");
            }
        }

        String tableName = aClass.getSimpleName();
        sqlBuilder.append("INSERT INTO ")
                .append(tableName.toLowerCase())
                .append(" (")
                .append(columns)
                .append(") VALUES (")
                .append(placeholders)
                .append(")");

        return sqlBuilder.toString();
    }
    @Override
    public ArrayList<T> findAll() {
        Connection connection = JdbcUtil.getConnection();
        Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Table tableAnnotation = clazz.getAnnotation(Table.class);
        String tableName = tableAnnotation.value();
        String sql = "SELECT * FROM " + tableName;

        // 执行查询并返回结果
        ArrayList<T> resultList = new ArrayList<>();
        try (PreparedStatement preparedStatement = connection.prepareStatement(sql);
             ResultSet resultSet = preparedStatement.executeQuery()) {
            while (resultSet.next()) {
                T entity = clazz.getDeclaredConstructor().newInstance();
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    field.set(entity, resultSet.getObject(field.getName()));
                }
                resultList.add(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultList;
    }

    @Override
    public T findById(int id) {
        Connection connection = JdbcUtil.getConnection();
//        Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Class<T> clazz = (Class<T>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        String simpleName = clazz.getSimpleName();
        System.out.println("simpleName=====>"+simpleName);
        Table tableAnnotation = clazz.getAnnotation(Table.class);
        String tableName = tableAnnotation.value();
        String sql = "SELECT * FROM " + tableName + " WHERE id = ?";
        try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
            preparedStatement.setInt(1, id);
            try (ResultSet resultSet = preparedStatement.executeQuery()) {
                if (resultSet.next()) {
                    T entity = clazz.getDeclaredConstructor().newInstance();
                    Field[] fields = clazz.getDeclaredFields();
                    for (Field field : fields) {
                        field.setAccessible(true);
                        field.set(entity, resultSet.getObject(field.getName()));
                    }
                    return entity;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public boolean delete(int id) {
        Connection connection = JdbcUtil.getConnection();
        Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Table tableAnnotation = clazz.getAnnotation(Table.class);
        String tableName = tableAnnotation.value();
        String sql = "DELETE FROM " + tableName + " WHERE id = ?";
        try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
            preparedStatement.setInt(1, id);
            int rowsAffected = preparedStatement.executeUpdate();
            return rowsAffected > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean update(T t) {
        Connection connection = JdbcUtil.getConnection();
        Class<?> aClass = t.getClass();
        String sql = generateUpdateSql(aClass);
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            Field[] fields = aClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                fields[i].setAccessible(true);
                Object value = fields[i].get(t);
                preparedStatement.setObject(i + 1, value);
            }
            int rowsAffected = preparedStatement.executeUpdate();
            return rowsAffected > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }

    private String generateUpdateSql(Class<?> aClass) {
        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append("UPDATE ").append(aClass.getSimpleName().toLowerCase()).append(" SET ");
        Field[] fields = aClass.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            String fieldName = fields[i].getName();
            sqlBuilder.append(fieldName).append(" = ?");
            if (i < fields.length - 1) {
                sqlBuilder.append(", ");
            }
        }
        return String.valueOf(sqlBuilder);
    }
}
